package com.hlf.common.utils.wx;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.hlf.common.constants.Constants;
import com.hlf.common.constants.WxRespCodeConstants;
import com.hlf.common.enums.WechatTemplateEnum;
import com.hlf.common.utils.*;
import com.hlf.modules.wechat.model.ConfigWechat;
import com.hlf.modules.wechat.model.ConfigWechatTemplate;
import com.hlf.modules.wechat.model.ConfigWechatVO;
import com.hlf.modules.wechat.service.ConfigWechatService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.net.URLEncoder;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author Administrator
 */
public class WxUtils {

    public static Logger logger = LoggerFactory.getLogger(WxUtils.class);

    private static ConfigWechatService configWechatService = SpringContextUtils.getBean("configWechatServiceImpl", ConfigWechatService.class);

    public static final PropertieUtil propertieUtil = SpringContextUtils.getPropertieUtil();

    /**
     * 点击推事件用户点击click类型按钮后，微信服务器会通过消息接口推送消息类型为event的结构给开发者（参考消息接口指南），
     * 并且带上按钮中开发者填写的key值，开发者可以通过自定义的key值与用户进行交互
     */
    public static final String BUTTON_TYPE_CLICK = "click";

    /**
     * 跳转URL用户点击view类型按钮后，微信客户端将会打开开发者在按钮中填写的网页URL，可与网页授权获取用户基本信息接口结合，获得用户基本信息。
     */
    public static final String BUTTON_TYPE_VIEW = "view";

    /**
     * 扫码推事件用户点击按钮后，微信客户端将调起扫一扫工具，完成扫码操作后显示扫描结果（如果是URL，将进入URL），且会将扫码的结果传给开发者，
     * 开发者可以下发消息
     */
    public static final String BUTTON_TYPE_SCANCODE_PUSH = "scancode_push";

    /**
     * scancode_waitmsg：扫码推事件且弹出“消息接收中”提示框用户点击按钮后，微信客户端将调起扫一扫工具，完成扫码操作后，
     * 将扫码的结果传给开发者，同时收起扫一扫工具，然后弹出“消息接收中”提示框，随后可能会收到开发者下发的消息
     */
    public static final String BUTTON_TYPE_SCANCODE_WAITMSG = "scancode_waitmsg";

    /**
     * 弹出系统拍照发图用户点击按钮后，微信客户端将调起系统相机，完成拍照操作后，会将拍摄的相片发送给开发者，并推送事件给开发者，同时收起系统相机，
     * 随后可能会收到开发者下发的消息
     */
    public static final String BUTTON_TYPE_PIC_SYSPHOTO = "pic_sysphoto";

    /**
     * 弹出拍照或者相册发图用户点击按钮后，微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。用户选择后即走其他两种流程
     */
    public static final String BUTTON_TYPE_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";

    /**
     * 弹出微信相册发图器用户点击按钮后，微信客户端将调起微信相册，完成选择操作后，将选择的相片发送给开发者的服务器，并推送事件给开发者，同时收起相册，
     * 随后可能会收到开发者下发的消息
     */
    public static final String BUTTON_TYPE_PIC_WEIXIN = "pic_weixin";

    /**
     * 弹出地理位置选择器用户点击按钮后，微信客户端将调起地理位置选择工具，完成选择操作后，将选择的地理位置发送给开发者的服务器，同时收起位置选择工具，
     * 随后可能会收到开发者下发的消息
     */
    public static final String BUTTON_TYPE_LOCATION_SELECT = "location_select";

    /**
     * 下发消息（除文本消息）用户点击media_id类型按钮后，微信服务器会将开发者填写的永久素材id对应的素材下发给用户，永久素材类型可以是图片、音频
     * 、视频、图文消息。请注意：永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id
     */
    public static final String BUTTON_TYPE_MEDIA_ID = "media_id";

    /**
     * 跳转图文消息URL用户点击view_limited类型按钮后，微信客户端将打开开发者在按钮中填写的永久素材id对应的图文消息URL，
     * 永久素材类型只支持图文消息。请注意：永久素材id必须是在“素材管理/新增永久素材”接口上传后获得的合法id。
     */
    public static final String BUTTON_TYPE_VIEW_LIMITED = "view_limited";

    /**
     * 获取access_token的接口地址（GET） 限2000（次/天）
     */
    public static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";

    /**
     * 网页授权获取access_token
     */
    public static final String OAUTH2_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    /**
     * 采用http GET方式请求获得jsapi_ticket
     */
    private static final String JSAPI_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";

    /**
     * 商家公众号accessToken key
     */
    public static final String MERCHANT_ACCESS_TOKEN_KEY = "merchantAccessToken";

    /**
     * 消费者公众号accessToken key
     */
    public static final String PERSONAL_ACCESS_TOKEN_KEY = "personalAccessToken";

    /**
     * 公众号jssdk调用凭证 key
     */
    public static final String JSAPI_TICKET_KEY = "jsApiTicket";

    /**
     * =============================微信公众号配置开始===================================
     */

    /**
     * 登录授权模板
     */
    public static final String WECHAT_OAUTH2_URL = propertieUtil.getPropertie("WECHAT_OAUTH2_URL");

    /**
     * 获取微信商家公众号配置信息
     *
     * @param topAgentId
     * @return
     */
    public static ConfigWechat getMerchantWechatConfig(Long topAgentId) {
        return configWechatService.selectMerchantConfigByAgentId(topAgentId);
    }

    /**
     * 获取微信商家公众号原始ID
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getMerchantOrginalId(Long topAgentId) {
        ConfigWechat cw = getMerchantWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getOriginalId();
    }

    /**
     * 获取微信商家公众号AppId
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getMerchantAppId(Long topAgentId) {
        ConfigWechat cw = getMerchantWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getAppId();
    }

    /**
     * 获取微信商家公众号AppSecret
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getMerchantAppSecret(Long topAgentId) {
        ConfigWechat cw = getMerchantWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getAppSecret();
    }

    /**
     * 获取微信商家公众号Token
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getMerchantToken(Long topAgentId) {
        ConfigWechat cw = getMerchantWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getToken();
    }

    /**
     * 获取微信消费者公众号信息配置
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static ConfigWechat getPersonalWechatConfig(Long topAgentId) {
        return configWechatService.selectPersonalConfigByAgentId(topAgentId);
    }

    /**
     * 获取微信消费者公众号原始ID
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getPersonalOrginalId(Long topAgentId) {
        ConfigWechat cw = getPersonalWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getOriginalId();
    }

    /**
     * 获取微信消费者公众号AppId
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getPersonalAppId(Long topAgentId) {
        ConfigWechat cw = getPersonalWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getAppId();
    }

    /**
     * 获取微信消费者公众号AppSecret
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getPersonalAppSecret(Long topAgentId) {
        ConfigWechat cw = getPersonalWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getAppSecret();
    }

    /**
     * 获取消费者公众号token
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月10日 下午9:05:53
     */
    public static String getPersonalToken(Long topAgentId) {
        ConfigWechat cw = getPersonalWechatConfig(topAgentId);
        if (cw == null) {
            return null;
        }
        return cw.getToken();
    }

    /**
     * @return
     * @author panjialong
     * @date 2017年7月18日 下午7:12:02
     */
    public static String getDefaultToken() {
        return getMerchantToken(Constants.DEFAULT_AGENT_ID);
    }

    /**
     * =============================微信公众号配置结束===================================
     * =======
     */

    /**
     * 获取接口访问凭证，需重新发送请求，更新token
     *
     * @param appid     凭证
     * @param appsecret 密钥
     * @return
     */
    public static Token getAccessToken(String appid, String appsecret) {
        Token token = null;
        String requestUrl = ACCESS_TOKEN_URL.replace("APPID", appid).replace("APPSECRET", appsecret);
        // 发起GET请求获取凭证
        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
//        try {
//            CloseableHttpClient httpClient = HttpsUtils.getHttpClient();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        if (null != jsonObject) {
            try {
                token = new Token();
                token.setAccessToken(jsonObject.getString("access_token"));
                token.setExpiresIn(jsonObject.getIntValue("expires_in"));
            } catch (JSONException e) {
                token = null;
                // 获取token失败
                logger.error("获取token失败, url:{}, errcode:{}, errmsg:{}", requestUrl, jsonObject.getIntValue("errcode"),
                        jsonObject.getString("errmsg"));
            }
        }
        return token;
    }

    /**
     * 获取缓存中的accessToken
     *
     * @param accessTokenKey 存储accessToken的key
     * @return
     */
    private static Token getAccessToken(String accessTokenKey) {
        return (Token) ServletContextUtil.get().getAttribute(accessTokenKey);
    }

    /**
     * 获取商家公众号缓存中的accessToken
     *
     * @param topAgentId
     * @return
     */
    public static Token getMerchantAccessToken(Long topAgentId) {
        return getAccessToken(MERCHANT_ACCESS_TOKEN_KEY + topAgentId);
    }

    /**
     * 获取消费者公众号缓存中的accessToken
     *
     * @param topAgentId
     * @return
     */
    public static Token getPersonalAccessToken(Long topAgentId) {
        return getAccessToken(PERSONAL_ACCESS_TOKEN_KEY + topAgentId);
    }

    /**
     * 获取商家公众号缓存中的accessToken值
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月12日 下午12:34:23
     */
    public static String getMerchantAccessTokenValue(Long topAgentId) {
        Token merchantAccessToken = getMerchantAccessToken(topAgentId);
        if (merchantAccessToken == null) {
            logger.error("获取 topAgentId = {} merchant accessToken失败", topAgentId);
            return null;
        }
        return merchantAccessToken.getAccessToken();
    }

    /**
     * 获取消费者公众号缓存中的accessToken值
     *
     * @param topAgentId
     * @return
     * @author panjialong
     * @date 2017年7月12日 下午12:34:23
     */
    public static String getPersonalAccessTokenValue(Long topAgentId) {
        Token personalAccessToken = getPersonalAccessToken(topAgentId);
        if (personalAccessToken == null) {
            logger.error("获取 topAgentId = {} personal accessToken失败", topAgentId);
            return null;
        }
        return personalAccessToken.getAccessToken();
    }

    /**
     * 设置商家公众号缓存中的accessToken
     *
     * @param token
     * @param topAgentId
     * @author panjialong
     * @date 2017年7月10日 下午8:57:57
     */
    public static void setMerchantAccessToken(Token token, Long topAgentId) {
        ServletContextUtil.get().removeAttribute(MERCHANT_ACCESS_TOKEN_KEY + topAgentId);
        ServletContextUtil.get().setAttribute(MERCHANT_ACCESS_TOKEN_KEY + topAgentId, token);
    }

    /**
     * 设置消费者公众号缓存中的accessToken
     *
     * @param token
     * @param topAgentId
     * @author panjialong
     * @date 2017年7月10日 下午8:57:26
     */
    public static void setPersonalAccessToken(Token token, Long topAgentId) {
        ServletContextUtil.get().removeAttribute(PERSONAL_ACCESS_TOKEN_KEY + topAgentId);
        ServletContextUtil.get().setAttribute(PERSONAL_ACCESS_TOKEN_KEY + topAgentId, token);
    }

    /**
     * 获取商家公众号用户授权信息
     *
     * @param topAgentId
     * @param code
     * @return
     */
    public static WeixinOauth2Token getMerchantOauth2AccessToken(Long topAgentId, String code) {
        return getOauth2AccessToken(getMerchantAppId(topAgentId), getMerchantAppSecret(topAgentId), code);
    }

    /**
     * 获取公众号用户授权信息
     *
     * @param topAgentId
     * @param code
     * @return
     */
    public static WeixinOauth2Token getOauth2AccessToken(Long topAgentId, String code) {
        return getOauth2AccessToken(getPersonalAppId(topAgentId), getPersonalAppSecret(topAgentId), code);
    }

    /**
     * 获取公众号jssdk调用凭证，需要重新发送请求，更新jsapiTicket
     *
     * @return
     */
    public static String getJsApiTicket(String accessToken) {
        String requestUrl = JSAPI_TICKET.replace("ACCESS_TOKEN", accessToken);
        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
        String ticket = "";
        // 如果请求成功
        if (null != jsonObject) {
            try {
                ticket = jsonObject.getString("ticket");
            } catch (JSONException e) {
                accessToken = null;
                // 获取jsApiTicket失败
                logger.error("获取jsApiTicket失败 errcode:{} errmsg:{}", jsonObject.get("errcode"),
                        jsonObject.getString("errmsg"));
            }
        }
        return ticket;
    }

    /**
     * 获取公众号jssdk调用凭证，从缓存中获取
     *
     * @return
     */
    public static String getJsApiTicket(Long topAgentId) {
        return (String) ServletContextUtil.get().getAttribute(getJsApiTikcetKey(topAgentId));
    }

    public static String getJsApiTikcetKey(Long topAgentId) {
        return JSAPI_TICKET_KEY + topAgentId;
    }

    /**
     * 获取用户授权信息
     *
     * @param appId
     * @param appSecret
     * @param code
     * @return
     */
    public static WeixinOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
        WeixinOauth2Token wat = null;
        try {
            // 拼接请求地址
            String requestUrl = OAUTH2_ACCESS_TOKEN_URL.replace("APPID", appId).replace("SECRET", appSecret).replace("CODE", code);
            // 获取网页授权凭证
            JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
            logger.info("获取用户授权信息,微信返回: {}", jsonObject);
            if (null != jsonObject) {
                if (jsonObject.get("errcode") == null) {
                    wat = new WeixinOauth2Token();
                    wat.setAccessToken(jsonObject.getString("access_token"));
                    wat.setExpiresIn(jsonObject.getIntValue("expires_in"));
                    wat.setRefreshToken(jsonObject.getString("refresh_token"));
                    wat.setOpenId(jsonObject.getString("openid"));
                    wat.setScope(jsonObject.getString("scope"));
                } else {
                    int errorCode = jsonObject.getIntValue("errcode");
                    String errorMsg = jsonObject.getString("errmsg");
                    logger.warn("获取网页授权凭证失败 {errcode:{}, errmsg:{}}", errorCode, errorMsg);
                }
            } else {
                logger.warn("无法获取授权凭证");
            }
        } catch (Exception e) {
            logger.error("获取网页授权凭证异常 appId = {}, appSecret = {}, code = {}", appId, appSecret, code);
        }
        return wat;
    }

    /**
     * 获取用户信息
     * @param openId
     * @param accessToken
     * @return
     */
    public static WxUserInfo getWxUserInfo(String openId, String accessToken) {
        String reqUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        return getUserInfo(openId,accessToken,reqUrl);
    }

    /**
     * 获取用户信息
     * @param openId
     * @param accessToken
     * @return
     */
    public static WxUserInfo getOauth2WxUserInfo(String openId, String accessToken) {
        String reqUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";
        return getUserInfo(openId,accessToken,reqUrl);
    }

    /**
     * 请求用户信息
     * @param openId
     * @param accessToken
     * @param reqUrl
     * @return
     */
    public static WxUserInfo getUserInfo(String openId, String accessToken,String reqUrl) {
        reqUrl = reqUrl.replace("ACCESS_TOKEN", accessToken);
        reqUrl = reqUrl.replace("OPENID", openId);

        Sender send = new Sender();
        WxUserInfo userInfo = new WxUserInfo();
        try {
            String resp = send.sendHttpReq(reqUrl, null, false, false, "UTF-8");
            logger.info("获取微信用户信息==========" + resp);
            if (resp == null) {
                logger.warn("获取微信用户信息为空 openId = {}, accessToken = {}", openId, accessToken);
                return null;
            }
            userInfo = JSONObject.parseObject(resp, WxUserInfo.class);
            // 如果access_token无效，则刷新（一般出现这种情况都是开发时刷新了生产的access_token）
            String errcode = userInfo.getErrcode();
            if (WxRespCodeConstants.APPSECRET_OR_ACCESS_TOKEN_INVALID.equals(errcode) || WxRespCodeConstants.ACCESS_TOKEN_TIMEOUT.equals(errcode)) {
                String token = AccessTokenUtil.initAndSetAccessToken();
                logger.error("{}获取access_token时AppSecret错误，或者access_token无效,重新刷新access_token",
                        WxRespCodeConstants.APPSECRET_OR_ACCESS_TOKEN_INVALID);
                getWxUserInfo(openId,token);
                return null;
            }
        } catch (Exception e) {
            logger.error("获取微信用户信息失败", e);
            e.printStackTrace();
        }
        return userInfo;
    }

    public static String getImgUrl(String ticket) throws Exception {
        String url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + URLEncoder.encode(ticket, "UTF-8");
        return url;
    }

    /**
     * 生成带参数的二维码
     *
     * @param token     接口调用凭证
     * @param scene_str 参数
     * @return
     * @throws Exception
     */
    public static String getImgUrl(String token, String scene_str) throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" + token;
        if (StringUtils.isEmpty(scene_str)) {
            scene_str = "NULL";
        }
        JSONObject obj = new JSONObject();
        obj.put("action_name", "QR_LIMIT_STR_SCENE");
        JSONObject actionInfoObj = new JSONObject();
        JSONObject sceneObj = new JSONObject();
        sceneObj.put("scene_str", scene_str);
        actionInfoObj.put("scene", sceneObj);
        obj.put("action_info", actionInfoObj);
        Sender send = new Sender();

        String result = send.sendHttpReq(url, obj, "UTF-8");
        obj = JSONObject.parseObject(result);
        if (obj.get("ticket") == null) {
            return null;
        }

        return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket="
                + URLEncoder.encode(obj.get("ticket").toString(), "UTF-8");
    }

    /**
     * 生成微信菜单
     *
     * @param obj
     * @param token
     * @return
     */
    public static boolean generateMenus(JSONObject obj, String token) {
        String reqUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token;
        try {
            JSONObject resp = CommonUtil.httpsRequest(reqUrl, "POST", obj.toJSONString());
            logger.info("resp: >>> ", resp);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 生成微信菜单
     *
     * @param obj
     * @param token
     * @return
     */
    public static String generateMenuss(JSONObject obj, String token) {
        String reqUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + token;
        try {
            JSONObject resp = CommonUtil.httpsRequest(reqUrl, "POST", obj.toJSONString());
            logger.info("resp: >>> errcode:{} errmsg:{}", resp.get("errcode"), resp.getString("errmsg"));
            if (resp.get("errcode").equals(0)) {
                return Constants.DEFAULT_MSG_SUCCESS;
            } else {
                return Constants.DEFAULT_MSG_FAILD;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return Constants.DEFAULT_MSG_FAILD;
        }
    }

    /**
     * 公众号推送消息
     *
     * @param token   调用接口凭证
     * @param openId  用户标识
     * @param content 发送内容
     * @throws Exception
     */
    public static void pushMessage(String token, String openId, String content) throws Exception {
        JSONObject obj = new JSONObject();
        JSONObject text = new JSONObject();
        text.put("content", content);
        obj.put("touser", openId);
        obj.put("msgtype", "text");
        obj.put("text", text);
        Sender sender = new Sender();
        String s = sender.sendHttpReq("https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + token,
                obj, "UTF-8");
        logger.info("公众号消息推送结果：{}", s);
    }

    /**
     * @param redirectUrl 页面跳转地址
     * @param appId       公众号appId
     * @param param       传递参数，建议格式为（a-b-c）
     * @author suyangsheng
     * @date 2017年3月22日 上午10:55:52
     * <p>
     * 获取微信授权url
     */
    public static String getAuthUrl(String redirectUrl, String appId, String param) {
        Objects.requireNonNull(appId, "APPID不能为空");
        Objects.requireNonNull(redirectUrl, "重定向URI不能为空");
        if (param == null) {
            param = "STATE";
        }
        redirectUrl = CommonUtil.urlEncodeUTF8(redirectUrl);
        return WECHAT_OAUTH2_URL.replace("APPID", appId).replace("REDIRECT_URI", redirectUrl).replace("STATE", param);
    }

    /**
     * 获取微信模板ID
     *
     * @param topAgentId
     * @param templateEnum
     * @return
     */
    public static String getWechatTemplateId(Long topAgentId, WechatTemplateEnum templateEnum) {
        ConfigWechatVO configWechatVO = configWechatService.selectMerchantConfigByAgentId(topAgentId);
        String templateId = "";
        if (configWechatVO != null) {
            Map<String, ConfigWechatTemplate> templates = configWechatVO.getWechatTemplate();
            ConfigWechatTemplate template = templates.get(templateEnum.getValue());
            if (template != null) {
                templateId = template.getTemplateContent();
            }
        }
        return templateId;
    }

    private static final String COLOR_BLACK = "#000000";

//    public static Map<String, TemplateData> packageOrder2TemplateDate(Order order, String remarkMsg) {
//        Map<String, TemplateData> m = new HashMap<String, TemplateData>();
//        TemplateData first = new TemplateData(null, null);
//        m.put("first", first);
//
//        TemplateData keyword1 = new TemplateData(COLOR_BLACK, order.getId().toString());
//        m.put("keyword1", keyword1);
//
//        TemplateData keyword2 = new TemplateData("#2bb723", AmountUtils.fenToYuan(order.getPayAmt()) + "元");
//        m.put("keyword2", keyword2);
//
//        TemplateData keyword3 = new TemplateData(COLOR_BLACK, order.getStoreName());
//        m.put("keyword3", keyword3);
//
//        TemplateData keyword4 = new TemplateData(COLOR_BLACK,
//                DateUtil.dateToString(order.getPayTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
//        m.put("keyword4", keyword4);
//
//        TemplateData keyword5 = new TemplateData(COLOR_BLACK, DictionaryMap.getValue("PAY_TYPE", order.getPayType()));
//        m.put("keyword5", keyword5);
//
//        TemplateData remark = new TemplateData(COLOR_BLACK, remarkMsg);
//        m.put("remark", remark);
//
//        return m;
//    }

    /**
     * 打包绑定店长/收银员模板消息
     *
     * @param StoreName
     * @param userName
     * @param bindName
     * @param bindTime
     * @param remarkMsg
     * @return
     * @author zouwenjun
     * @date 2017年8月17日 上午11:53:00
     */
    public static Map<String, TemplateData> packageBindMC2TemplateDate(String StoreName, String userName, String bindName,
                                                                       String bindTime, String remarkMsg) {
        Map<String, TemplateData> m = new HashMap<String, TemplateData>();
        TemplateData first = new TemplateData(COLOR_BLACK, "恭喜您成为“" + StoreName + "”的" + bindName);
        m.put("first", first);

        TemplateData keyword1 = new TemplateData(COLOR_BLACK, userName);
        m.put("keyword1", keyword1);

        TemplateData keyword2 = new TemplateData(COLOR_BLACK, bindName);
        m.put("keyword2", keyword2);

        TemplateData keyword3 = new TemplateData(COLOR_BLACK, bindTime);
        m.put("keyword3", keyword3);

        TemplateData remark = new TemplateData(COLOR_BLACK, remarkMsg);
        m.put("remark", remark);

        return m;
    }

    /**
     * 打包解绑店长/收银员模板消息
     *
     * @param StoreName
     * @param userName
     * @param bindName
     * @param bindTime
     * @param remarkMsg
     * @return
     * @author zouwenjun
     * @date 2017年8月17日 上午11:54:59
     */
    public static Map<String, TemplateData> packageUnBindMC2TemplateDate(String StoreName, String userName, String bindName,
                                                                         String bindTime, String remarkMsg) {
        Map<String, TemplateData> m = new HashMap<String, TemplateData>();
        TemplateData first = new TemplateData(COLOR_BLACK, "您已与“" + StoreName + "”解绑成功");
        m.put("first", first);

        TemplateData keyword1 = new TemplateData(COLOR_BLACK, userName);
        m.put("keyword1", keyword1);

        TemplateData keyword2 = new TemplateData(COLOR_BLACK, bindName);
        m.put("keyword2", keyword2);

        TemplateData keyword3 = new TemplateData(COLOR_BLACK, bindTime);
        m.put("keyword3", keyword3);

        TemplateData remark = new TemplateData(COLOR_BLACK, remarkMsg);
        m.put("remark", remark);

        return m;
    }

    /**
     * 打包会员等级升级模板消息
     *
     * @param StoreName
     * @param oldMemberLV
     * @param newMemberLV
     * @param rate
     * @param remarkMsg
     * @return
     * @author zouwenjun
     * @date 2017年8月17日 下午1:45:18
     */
    public static Map<String, TemplateData> packageMemberLVChange2TemplateDate(String StoreName, String oldMemberLV, String newMemberLV,
                                                                               String rate, String remarkMsg) {
        Map<String, TemplateData> m = new HashMap<String, TemplateData>();
        TemplateData first = new TemplateData(COLOR_BLACK, "恭喜您在“" + StoreName + "”的会员等级升级啦");
        m.put("first", first);

        TemplateData keyword1 = new TemplateData(COLOR_BLACK, oldMemberLV);
        m.put("keyword1", keyword1);

        TemplateData keyword2 = new TemplateData(COLOR_BLACK, newMemberLV);
        m.put("keyword2", keyword2);

        TemplateData keyword3 = new TemplateData(COLOR_BLACK, rate);
        m.put("keyword3", keyword3);

        TemplateData remark = new TemplateData(COLOR_BLACK, remarkMsg);
        m.put("remark", remark);

        return m;
    }

    public static JSONObject sendTemplateMsg(String accessToken, WechatTemplate wechatTemplate) throws Exception {
        Sender sender = new Sender();
        JSONObject obj = (JSONObject) JSONObject.toJSON(wechatTemplate);
        String requestURL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
        String result = sender.sendHttpReq(requestURL, obj, "UTF-8");
        JSONObject res = JSON.parseObject(result);
        logger.info("模板消息发送结果{}", result);
        return res;
    }

    /**
     * 调用微信jssdk前置
     *
     * @param url
     * @param topAgentId
     * @return
     * @throws Exception
     */
    public static Map<String, Object> wxScan(String url, Long topAgentId) throws Exception {

        Map<String, Object> map = new TreeMap<>();
        map.put("noncestr", IdWorkerFactory.nextId());
        map.put("jsapi_ticket", WxUtils.getJsApiTicket(topAgentId));
        map.put("timestamp", System.currentTimeMillis());
        map.put("url", url);

        StringBuilder signSrc = new StringBuilder(50);
        Set<Entry<String, Object>> entrySet = map.entrySet();
        for (Entry<String, Object> entry : entrySet) {
            signSrc.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        signSrc.deleteCharAt(signSrc.lastIndexOf("&"));

        logger.info("签名源=======" + signSrc);
        String sign = SignUtils.signWithSha1(signSrc.toString());
        map.put("signature", sign);
        map.put("appId", WxUtils.getMerchantAppId(topAgentId));
        return map;
    }

    public static void main(String[] args) throws Exception {

        JSONObject obj = new JSONObject();

        List<Map<String, Object>> buttonList = new ArrayList<>();

        Map<String, Object> button1 = new HashMap<>();
        List<Map<String, Object>> subButtonList1 = new ArrayList<>();

        Map<String, Object> sub_button1 = new HashMap<>();
        sub_button1.put("name", "商家注册");
        sub_button1.put("type", WxUtils.BUTTON_TYPE_VIEW);
        sub_button1.put("url", "http://test.halopay.cn/register/toRegister");
        sub_button1.put("key", "personal_register");
        subButtonList1.add(sub_button1);

        Map<String, Object> sub_button2 = new HashMap<>();
        sub_button2.put("name", "商家中心");
        sub_button2.put("type", WxUtils.BUTTON_TYPE_VIEW);
        sub_button2.put("url", "http://test.halopay.cn/merchant/center");
        sub_button2.put("key", "view_to_center");
        subButtonList1.add(sub_button2);

        Map<String, Object> sub_button3 = new HashMap<>();
        sub_button3.put("name", "绑定台卡");
        sub_button3.put("type", WxUtils.BUTTON_TYPE_SCANCODE_PUSH);
        sub_button3.put("key", "rselfmenu_0_1");
        subButtonList1.add(sub_button3);

        Map<String, Object> sub_button4 = new HashMap<>();
        sub_button4.put("name", "扫码上班");
        sub_button4.put("type", WxUtils.BUTTON_TYPE_SCANCODE_PUSH);
        sub_button4.put("key", "rselfmenu_0_2");
        subButtonList1.add(sub_button4);

        button1.put("name", "商家");
        button1.put("sub_button", subButtonList1.toArray());
        buttonList.add(button1);

        Map<String, Object> button2 = new HashMap<>();
        // List<Map<String, Object>> subButtonList2 = new ArrayList<>();

        button2.put("name", "银联扫码");
        button2.put("type", WxUtils.BUTTON_TYPE_VIEW);
        button2.put("key", "view_to_unionscan");
        button2.put("url", "http://test.halopay.cn/pay/scan"); //
        // button2.put("sub_button", subButtonList2.toArray());
        buttonList.add(button2);

        obj.put("button", buttonList);
        System.out.println(obj);

        // Map<String, Object> button3 = new HashMap<>();
        // List<Map<String, Object>> subButtonList3 = new ArrayList<>();

        // String url = getImgUrl(
        // "U_mPvccjKjqKKRkdllSDZhjzRToi_7xkBpFd4ix9A_PUVtEeYGznebbZ3YQtLpB3J4E8dopyExh2G7kwvXL4tayNHtnnwNZPnMQ3naoXcYuzP32Z1u--wSvpcZKOmufBQTEcAGAKNY",
        // " ");
        // System.out.println(url);
        // OrderVO order = new OrderVO();
        // order.setId(111111111111L);
        // order.setStoreName("测试门店");
        // order.setPayAmt(100);
        // order.setPayTime(new Date());
        // String accessToken =
        // "HhQ2CimuNKjGi7-V1bh60qaSIALZI9ZMY6pE8AGP2WEdVNU0BUYBg5YiycSOXPhXCoqA4dE0aZjSN6iuXumiNhhkVaKR9hcjCCJrjSRXcwP9Rj4fZV3FoLP0cfWZEeLUGMXeACAQWH";
        // WechatTemplate wechatTemplate =
        // packageTemplateDate("oi_nO0bV44qwnAsg6mHhYtzr3mPI", null, "#2bb723",
        // "测试模板发送",
        // order);
        // sendTemplateMsg(accessToken, wechatTemplate);
        // String content =
        // "你好，欢迎关注雏蜂金服，\n\n顾客通过关注微信公众号，在雏蜂金服旗下合作商家处，微信支付即可享受商家配置的门店会员优惠折扣。\n\n更多特权请持续关注！\n\n<a
        // href=\""+SERVER_URI+"/personal/toBindMobilePhone\">点我补充会员资料</a>";
        // pushMessage(accessToken, "of_zO0drS7EkyFYycWmOwBTXhrKY", content);
    }

}
